library(ggplot2)
library(tibble)
library(scales)
library(ggthemes)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
mpg <- ggplot2::mpg
mpg %>% ggplot(aes(cty, hwy, colour = manufacturer)) +
geom_point(show.legend = FALSE, size = 4) +
geom_point(show.legend = FALSE, size = 1, colour = "#F19F19") +
theme_void() +
scale_color_brewer()
### EX 2
# Trying out the function
polar_art(42, 100, c('blue', 'green', 'orange'))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# altering the function
polar_art2 <- function(seed, n, palette) {
# set the state of the random number generator
set.seed(seed)
# data frame containing random values for
# aesthetics we might want to use in the art
dat <- tibble(
x0 = runif(n),
y0 = runif(n),
x1 = x0 + runif(n, min = -.2, max = .2),
y1 = y0 + runif(n, min = -.2, max = .2),
shade = runif(n),
size = runif(n)
)
# plot segments in various colours, using
# polar coordinates and a gradient palette
dat |>
ggplot(aes(
x = x0,
y = y0,
xend = x1,
yend = y1,
colour = shade,
size = size
)) +
geom_segment(show.legend = FALSE) +
#coord_polar() + remove polar
scale_y_continuous(expand = c(0, 0)) +
scale_x_continuous(expand = c(0, 0)) +
scale_colour_gradientn(colours = palette) +
scale_size(range = c(0, 10)) +
theme_void()
}
polar_art2(42, 100, c('blue', 'green', 'orange')) # confetti
The reason that you would name multiple files instead of using git version control is because each creation is a new piece of art. We aren’t working toward an answer but rather a goal of making something aesthetically pleasing. If we were to write over a single file we could lose our previous creations.
show_col(sample_canva(3))
show_col(sample_canva(10))
# write my own palette generator
sample_named_colours <- function(n){
sample(colours(distinct = TRUE), n)
}
polar_art(runif(1, 0, 150), runif(1, 10, 150), sample_named_colours(15))
# Break the palette
sample_canva <- function(seed = NULL) {
if(!is.null(seed)) set.seed(seed)
sample(unlist(ggthemes::canva_palettes), 1)[[1]]
}
show_col(sample_canva(3))
dat <- sample_data(n = 1000, seed = 1) |>
mutate(y1 = y0, size = size * 4)
polar_styled_plot(palette = sample_canva(52)) +
geom_segment(data = dat,
lineend = "round",
colour = "#222222") +
geom_point(data = dat)
# write a new function
my_styled_plot <- function(data = NULL, palette) {
ggplot(
data = data,
mapping = aes(
x = x0,
y = y0,
xend = x1,
yend = y1,
fill = shade,
alpha = size
)) +
coord_polar(clip = "off") +
scale_y_continuous(
expand = c(0, 0),
limits = c(0, 1),
oob = scales::oob_keep
) +
scale_x_continuous(
expand = c(0, 0),
limits = c(0, 1),
oob = scales::oob_keep
) +
scale_fill_gradientn(colours = palette) +
scale_alpha(range = c(0.2, 1)) +
theme_void() +
guides(
fill = guide_none(),
alpha = guide_none(),
colour = guide_none(),
size = guide_none()
)
}
my_styled_plot(palette = sample_canva(7)) +
geom_point(data = dat)
library(dplyr)
library(purrr)
##
## Attaching package: 'purrr'
## The following object is masked from 'package:scales':
##
## discard
library(tibble)
library(ggplot2)
library(ggthemes)
library(ambient)
x_coords <- seq(from = 0, to = 1, length.out = 800)
y_coords <- seq(from = 0, to = 1, length.out = 800)
canvas <- long_grid(x = x_coords, y = y_coords)
freq_spatial <- 10
seed_spatial <- 56
seed_palette <- 121
dat <- canvas |>
mutate(
paint = gen_perlin(
x = x,
y = y,
frequency = freq_spatial,
seed = seed_spatial
)
)
pic <- dat |>
ggplot(aes(x, y, fill = paint)) +
geom_raster(show.legend = FALSE) +
theme_void() +
coord_equal() +
scale_x_continuous(expand = c(0, 0)) +
scale_y_continuous(expand = c(0, 0)) +
scale_fill_gradientn(
colours = sample_canva(seed_palette)
)
plot(pic)
# call make noise art
make_noise_art(
generator = gen_worley,
seed = runif(1,50,1000),
palette = sample_canva(100),
value = "distance",
pixels = 1000
)
Nice art!
To create a nice file name I would first set a variable for each
differing input. I would then include this var as a string in the
filename = here() section. this would allow me to create a
file name with a specialized name.
gen_gate <- function(x, y, frequency, ...) {
lf <- gen_simplex(x, y, frequency = frequency, ...)
mf <- gen_simplex(x, y, frequency = frequency * 20, ...)
hf <- gen_simplex(x, y, frequency = frequency * 99, ...)
gate <- gen_simplex(x, y, frequency = frequency * 10, ...)
gate <- normalise(gate)
paint <- lf +
(mf + 2) * (gate >= .2 & gate < .8) +
(hf + 2) * (gate >= .1)
return(paint)
}
pal <- sample_canva(seed = 99)
fractal_art(billow, gen_worley, palette = pal, seed = 42, octaves = 19)
fractal_art(billow, gen_worley, palette = pal, seed = 1, octaves = 1) # ewwww
Wow that is ugly
# my own function
gen_custom <- function(x, y, frequency, ...) {
simplex1 <- gen_simplex(x, y, frequency = frequency, ...)
simplex2 <- gen_simplex(x, y, frequency = frequency * 2, ...)
perlin <- gen_perlin(x, y, frequency = frequency * 0.5, ...)
custom_gen <- (simplex1 + simplex2) * perlin
return(normalise(custom_gen))
}
fractal_art(billow, gen_custom, palette = pal, seed = 1, octaves = 1)
The time taken for curl-art-1 is 1.56seconds and the time taken for curl-art-2 is 3.74 seconds.
pic1
pic2
smol_grid <- long_grid(x = 1:20, y = 1:20)
pic1 <- smol_grid |>
mutate(x = normalise(x), y = normalise(y)) |>
curl_art(noise = gen_simplex, fractal = fbm, octaves = 19, freq_init = .7)
pic1
library(dplyr)
library(tibble)
library(ggplot2)
library(ggforce)
library(deldir)
## deldir 1.0-9 Nickname: "Partial Distinction"
##
## The syntax of deldir() has changed since version
## 0.0-10. In particular the "dummy points" facility
## (which was a historical artifact) has been removed.
## In the current version, 1.0-8, an argument "id" has
## been added to deldir(). This new argument permits the
## user to specifier identifiers for points. The default
## behaviour is to continue using the indices of the
## points to identify them. In view of the fact that
## point identifiers may be user-supplied, the arguement
## "number", in plot.deldir() and plot.tile.list(), has
## had its name changed to "labelPts", and the argument
## "nex" in plot.deldir() has had its name changed to
## "lex". In addition the name of the forth component
## of the "cmpnt_col" argument in plot.deldir() has been
## changed from "num" to "labels". There is a new
## function getNbrs(), and the function tileInfo() has
## been modified to include output from getNbrs().
## Please consult the help.
library(ggthemes)
library(voronoise)
library(tictoc)
library(ambient)
library(purrr)
library(tidyr)
library(stringr)
sample_canva2 <- function(seed = NULL, n = 4) {
if(!is.null(seed)) set.seed(seed)
sample(ggthemes::canva_palettes, 1)[[1]] |>
(\(x) colorRampPalette(x)(n))()
}
choose_rectangle <- function(blocks) {
sample(nrow(blocks), 1, prob = blocks$area)
}
choose_break <- function(lower, upper) {
round((upper - lower) * runif(1))
}
create_rectangles <- function(left, right, bottom, top, value) {
tibble(
left = left,
right = right,
bottom = bottom,
top = top,
width = right - left,
height = top - bottom,
area = width * height,
value = value
)
}
split_rectangle_x <- function(rectangle, new_value) {
with(rectangle, {
split <- choose_break(left, right)
new_left <- c(left, left + split)
new_right <- c(left + split, right)
new_value <- c(value, new_value)
create_rectangles(new_left, new_right, bottom, top, new_value)
})
}
split_rectangle_y <- function(rectangle, new_value) {
with(rectangle, {
split <- choose_break(bottom, top)
new_bottom <- c(bottom, bottom + split)
new_top <- c(bottom + split, top)
new_value <- c(value, new_value)
create_rectangles(left, right, new_bottom, new_top, new_value)
})
}
split_rectangle <- function(rectangle, value) {
if(runif(1) < .5) {
return(split_rectangle_x(rectangle, value))
}
split_rectangle_y(rectangle, value)
}
split_block <- function(blocks, value) {
old <- choose_rectangle(blocks)
new <- split_rectangle(blocks[old, ], value)
bind_rows(blocks[-old, ], new)
}
subdivision <- function(ncol = 1000,
nrow = 1000,
nsplits = 50,
seed = NULL) {
if(!is.null(seed)) set.seed(seed)
blocks <- create_rectangles(
left = 1,
right = ncol,
bottom = 1,
top = nrow,
value = 0
)
reduce(1:nsplits, split_block, .init = blocks)
}
develop <- function(div, seed = NULL) {
div |>
ggplot(aes(
xmin = left,
xmax = right,
ymin = bottom,
ymax = top,
fill = value
)) +
geom_rect(
colour = "#F19918", # I changed this background color
size = 3,
show.legend = FALSE
) +
scale_fill_gradientn(
colours = sample_canva2(seed)
) +
coord_equal() +
theme_void()
}
pic <- subdivision(seed = 10) |> develop() # I changed this line
plot(pic)
sample_canva2 <- function(seed = NULL, n = 4) {
if(!is.null(seed)) set.seed(seed)
sample(ggthemes::canva_palettes, 1)[[1]] |>
(\(x) colorRampPalette(x)(n))()
}
choose_rectangle <- function(blocks) {
sample(nrow(blocks), 1, prob = blocks$area)
}
choose_break <- function(lower, upper) {
round((upper - lower) * runif(1))
}
create_rectangles <- function(left, right, bottom, top, value) {
tibble(
left = left,
right = right,
bottom = bottom,
top = top,
width = right - left,
height = top - bottom,
area = width * height,
value = value
)
}
split_rectangle_x <- function(rectangle, new_value) {
with(rectangle, {
split <- choose_break(left, right)
new_left <- c(left, left + split)
new_right <- c(left + split, right)
new_value <- c(value, new_value)
create_rectangles(new_left, new_right, bottom, top, new_value)
})
}
split_rectangle_y <- function(rectangle, new_value) {
with(rectangle, {
split <- choose_break(bottom, top)
new_bottom <- c(bottom, bottom + split)
new_top <- c(bottom + split, top)
new_value <- c(value, new_value)
create_rectangles(left, right, new_bottom, new_top, new_value)
})
}
split_rectangle <- function(rectangle, value) {
if(runif(1) < .5) {
return(split_rectangle_x(rectangle, value))
}
split_rectangle_y(rectangle, value)
}
split_block <- function(blocks, value) {
old <- choose_rectangle(blocks)
new <- split_rectangle(blocks[old, ], value)
bind_rows(blocks[-old, ], new)
}
subdivision <- function(ncol = 1000,
nrow = 1000,
nsplits = 50,
seed = NULL) {
if(!is.null(seed)) set.seed(seed)
blocks <- create_rectangles(
left = 1,
right = ncol,
bottom = 1,
top = nrow,
value = 0
)
reduce(1:nsplits, split_block, .init = blocks)
}
fill_rectangle <- function(left, right, bottom, top, width,
height, area, value, nshades = 100) {
set.seed(value)
fractals <- list(billow, fbm, ridged)
generators <- list(gen_simplex, gen_perlin, gen_worley)
expand_grid(
x = left:right,
y = bottom:top,
) |>
mutate(
fill = 10 * value + fracture(
x = x * sample(-3:3, 1),
y = y * sample(-3:3, 1),
noise = sample(generators, 1)[[1]],
fractal = sample(fractals, 1)[[1]],
octaves = sample(10, 1),
frequency = sample(10, 1) / 20,
value = "distance2"
) |>
normalise(to = c(1, nshades)) |>
round()
)
}
draw_mosaic <- function(dat, palette) {
background <- sample(palette, 1)
dat |>
ggplot(aes(x, y, fill = fill)) +
geom_tile(show.legend = FALSE, colour = background, size = .2) +
scale_size_identity() +
scale_colour_gradientn(colours = palette) +
scale_fill_gradientn(colours = palette) +
scale_x_continuous(expand = expansion(add = 5)) +
scale_y_continuous(expand = expansion(add = 5)) +
coord_equal() +
theme_void() +
theme(plot.background = element_rect(fill = background))
}
mosaica <- function(ncol = 60,
nrow = 60,
nsplits = 30,
seed = NULL) {
subdivision(ncol, nrow, nsplits, seed) |>
pmap_dfr(fill_rectangle) |>
slice_sample(prop = .995) |>
filter(!is.na(fill)) |>
draw_mosaic(palette = sample_canva2(seed))
}
pic <- mosaica(ncol = 100, nrow = 100, nsplits = 200, seed = 42) # I changed this line
plot(pic)
sample_canva2 <- function(seed = NULL, n = 4) {
if(!is.null(seed)) set.seed(seed)
sample(ggthemes::canva_palettes, 1)[[1]] |>
(\(x) colorRampPalette(x)(n))()
}
unboxy <- function(iterations, layers) {
coeffs <- array(
data = runif(9 * layers, min = -1, max = 1),
dim = c(3, 3, layers)
)
point0 <- matrix(
data = runif(3, min = -1, max = 1),
nrow = 1,
ncol = 3
)
funs <- list(
function(point) point + (sum(point ^ 2)) ^ (1/3),
function(point) sin(point),
function(point) 2 * sin(point)
)
update <- function(point, t) {
l <- sample(layers, 1)
f <- sample(funs, 1)[[1]]
z <- point[3]
point[3] <- 1
point <- f(point %*% coeffs[,,l])
point[3] <- (point[3] + z)/2
return(point)
}
points <- accumulate(1:iterations, update, .init = point0)
points <- matrix(unlist(points), ncol = 3, byrow = TRUE)
points <- as_tibble(as.data.frame(points))
names(points) <- c("x", "y", "val")
return(points)
}
set.seed(2) # Change the seed to generate a different random pattern
dat <- unboxy(iterations = 800, layers = 4) # Adjust the iterations and layers
pic <- ggplot(dat, aes(x, y, fill = val)) +
theme_void() +
coord_equal(xlim = c(-2.5, 2.5), ylim = c(-2.5, 2.5)) +
scale_fill_gradientn(colours = sample_canva2()) +
scale_x_continuous(expand = c(0, 0)) +
scale_y_continuous(expand = c(0, 0))
pic2 <- pic +
geom_voronoi_tile(
colour = "#FF0000", # Change the tile color
size = 0.2,
show.legend = FALSE
)
plot(pic2)
sample_canva2 <- function(seed = NULL, n = 4) {
if(!is.null(seed)) set.seed(seed)
sample(ggthemes::canva_palettes, 1)[[1]] |>
(\(x) colorRampPalette(x)(n))()
}
unboxy <- function(iterations, layers) {
coeffs <- array(
data = runif(9 * layers, min = -1, max = 1),
dim = c(3, 3, layers)
)
point0 <- matrix(
data = runif(3, min = -1, max = 1),
nrow = 1,
ncol = 3
)
funs <- list(
function(point) point + (sum(point ^ 2)) ^ (1/3),
function(point) sin(point),
function(point) 2 * sin(point)
)
update <- function(point, t) {
l <- sample(layers, 1)
f <- sample(funs, 1)[[1]]
z <- point[3]
point[3] <- 1
point <- f(point %*% coeffs[,,l])
point[3] <- (point[3] + z)/2
return(point)
}
points <- accumulate(1:iterations, update, .init = point0)
points <- matrix(unlist(points), ncol = 3, byrow = TRUE)
points <- as_tibble(as.data.frame(points))
names(points) <- c("x", "y", "val")
return(points)
}
sift <- function(data) {
data <- data |>
group_by(group) |>
mutate(
tilesize = (max(x) - min(x)) * (max(y) - min(y)),
x = if_else(tilesize > .02, x, x + rnorm(1)/10),
y = if_else(tilesize > .02, y, y + rnorm(1)/10)
) |>
ungroup()
return(data)
}
shake <- function(data) {
data |>
group_by(group) |>
mutate(
x = x + runif(1)/10,
y = y + runif(1)/10
) |>
ungroup()
}
voronoi_baroque <- function(
seed,
perturb,
max.radius = NULL,
radius = 0,
expand = 0,
...
) {
set.seed(seed)
blank <- ggplot(mapping = aes(x, y, fill = val)) +
theme_void() +
coord_equal(xlim = c(-2.75, 2.75), ylim = c(-2.75, 2.75)) +
guides(fill = guide_none(), alpha = guide_none()) +
scale_fill_gradientn(colours = sample_canva2(seed)) +
scale_alpha_identity() +
scale_x_continuous(expand = c(0, 0)) +
scale_y_continuous(expand = c(0, 0))
blank +
geom_voronoise(
data = unboxy(iterations = 10000, layers = 5),
perturb = perturb,
max.radius = max.radius,
radius = radius,
expand = expand,
...,
show.legend = FALSE
)
}
pic <- voronoi_baroque(99, sift) # this is where the changes occur # i used the value of 99
# and am using sift instead of shake
plot(pic)
#remotes::install_github("paezha/truchet")
library(truchet)
set.seed(456) # change the seed
mosaic <- st_truchet_ms(
tiles = c("+", "dl", "ane"), # Change the tiles to create a different pattern
p1 = 0.3, # Adjust the probability of scale 1
p2 = 0.4, # Adjust the probability of scale 2
p3 = 0.3, # Adjust the probability of scale 3
xlim = c(1, 6),
ylim = c(1, 6)
)
pic <- mosaic |>
ggplot(aes(fill = color)) +
geom_sf(color = NA, show.legend = FALSE) +
scale_fill_gradientn(colours = c("#FF00A0", "#10AF00")) + # Change the gradient colors
theme_void()
plot(pic)
This looks really weird!
Here is an output combining Truchet and some visual
library(truchet)
# step 1
set.seed(456) # change the seed
mosaic <- st_truchet_ms(
tiles = c("+", "dl", "ane"), # Change the tiles to create a different pattern
p1 = 0.3, # Adjust the probability of scale 1
p2 = 0.4, # Adjust the probability of scale 2
p3 = 0.3, # Adjust the probability of scale 3
xlim = c(1, 6),
ylim = c(1, 6)
)
pic <- mosaic |>
ggplot(aes(fill = 1)) +
geom_sf(color = NA, show.legend = FALSE) +
scale_fill_gradientn(colours = c("#FF00A0", "#10AF00")) + # Change the gradient colors
theme_void()
# step 2
combine_methods <- function(seed, n, palette) {
set.seed(seed)
mosaic <- st_truchet_ms(
tiles = c("+", "dl", "ane"),
p1 = 0.3,
p2 = 0.4,
p3 = 0.3,
xlim = c(1, 6),
ylim = c(1, 6)
)
pic <- mosaic |>
ggplot(aes(fill = 1)) +
geom_sf(color = NA, show.legend = FALSE) +
scale_fill_gradientn(colours = c("#FF00A0", "#10AF00")) +
theme_void()
dat <- tibble(
x0 = runif(n),
y0 = runif(n),
x1 = x0 + runif(n, min = -.2, max = .2),
y1 = y0 + runif(n, min = -.2, max = .2),
shade = runif(n),
size = runif(n)
)
pic +
geom_segment(data = dat, aes(x = x0, y = y0, xend = x1,
yend = y1, colour = shade,
size = size), show.legend = FALSE) +
coord_polar() +
scale_y_continuous(expand = c(0, 0)) +
scale_x_continuous(expand = c(0, 0)) +
scale_colour_gradientn(colours = palette) +
scale_size(range = c(0, 10))
}
# step 3
combined_figure <- combine_methods(123, 200, c('blue', 'green', 'orange'))
#combined_figure
I keep running into this error so I will hault my trying.
I learned a lot in this choya, for example I had never even thought to take a set of data like the mpg and use that to make data that is pretty. Usually when I think of visualizing data, I imagine some plots that show trends or clustering. This exercise showed me a new way of thinking about data visualization and I find it really interesting. I learned that I was not able to create an image that mixed items from task 1 and task 2 together. I was familiar with ggplot and dplyr for data manipulation but that is about it. There were a lot of new concepts that were covered in this assignment.